using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.ObjectModel;
using Granite.Eventing;
using System.Collections.Specialized;

namespace Granite.Commons.Tests.Collections
{
    [TestClass()]
    public class CollectionChangedEventManagerTests
    {


        [TestMethod()]
        public void CollectionChangedEventManager_MemoryTest1()
        {
            var source = new ObservableCollection<int>();
            var target = new Token();
            var em = new CollectionChangedEventManager(source);

            em.AddHandler(target.Proxy);

            var wr1 = new WeakReference(target);
            var wr2 = new WeakReference(em);

            TestUtilities.GCCycle();

            source.Add(1);
            source.Add(2);
            source.Add(3);
            Assert.AreEqual(3, target.Count);

            target = null;
            em = null;

            TestUtilities.GCCycle();


            source.Add(4);

            Assert.IsFalse(wr1.IsAlive);

            TestUtilities.GCCycle();


            Assert.IsFalse(wr2.IsAlive);

        }



        [TestMethod()]
        public void CollectionChangedEventManager_MemoryTest2()
        {
            var source = new ObservableCollection<int>();
            var target = new Token();
            var em = new CollectionChangedEventManager(source);
            em.AddHandler(target.Proxy);

            var wr1 = new WeakReference(target);
            var wr2 = new WeakReference(em);

            source.Add(1);
            source.Add(2);
            source.Add(3);
            Assert.AreEqual(3, target.Count);


            em.RemoveHandler(target.Proxy);

            source.Add(4);
            Assert.AreEqual(3, target.Count);

            target = null;
            em = null;

            TestUtilities.GCCycle();

            source.Add(5);
            Assert.IsFalse(wr1.IsAlive);
            Assert.IsFalse(wr2.IsAlive);

        }

        class Token
        {
            private Listener<NotifyCollectionChangedEventArgs> proxy;
            public Token()
            {
				proxy = new Listener<NotifyCollectionChangedEventArgs>(EventHandler);
            }

            public int Count { get; set; }
            public void EventHandler(object sender, EventArgs e)
            {
                Count += 1;
            }
			public Listener<NotifyCollectionChangedEventArgs> Proxy
            {
                get { return proxy; }
            }
        }
    }
}
